/**
 * @file MeanShift.h
 * @author enemy1205 (enemy1205@qq.com)
 * @date 2021-09-02
 */
#pragma once
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <algorithm>
#include <vector>
#include <stack>

using namespace std;
using namespace cv;
const double PI = 3.14159265358979323846264338327950288;
class MeanShift {
    const int max_itr = 8;//最大迭代次数
    const double color_threshold = 0.05;//颜色阈值
    Mat src;//源图
    Mat img_Luv;//转Luv后图片
    Mat Label;//区域标注图
    Mat filt;//滤波后结果
    Mat dst;//最终结果
    int num;//每个区域中点的数量
    vector<int> pointnum;//存储每个区域点的个数
    int region;//区域总数
    int displacement[8][2] = {
            {-1, -1},
            {-1, 0},
            {-1, 1},
            {0,  -1},
            {0,  1},
            {1,  -1},
            {1,  0},
            {1,  1}
    };//邻点偏移位置矩阵
    vector<Vec3b> Colors;
    const double EQUAL_ERR = 1e-10;//位置偏移均方差
    const int minarea = 20;//分割最小面积，否则合并至最近像素区域
    vector<vector<int>> adjoint_table; //相邻表
    vector<int> adjoint_table_head;//作为adjoint_table序列中根元素的信息
public:
    MeanShift(string &);//构造函数
    void help();//使用说明
    void meanshiftFilter(const double, const double); //均值偏移滤波器
    void meanshiftSegmentation();//均值偏移分割
    void buildLabel(const double);//建立区域标签
    void buildChain();// 建立相邻表
    void mergeSimilarity(int, const double);//合并相似区域
    void removeSmallArea();//移除小区域
    void buildResult();//绘制结果
    Mat &getResult() { return dst; }//返回结果图像
};